package ar.com.gals.controller;

import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.sf.json.JSONObject;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import ar.com.gals.configuration.Configuration;
import ar.com.gals.domain.Archivo;
import ar.com.gals.error.GalsException;
import ar.com.gals.service.ArchivoService;


@Controller
@RequestMapping(value = "/Upload")
public class ArchivoController extends AbstractController {
	
	
	@RequestMapping(value = "/ListaPrecios", method = RequestMethod.POST)
	public @ResponseBody String uploadListaPrecios(MultipartHttpServletRequest request, HttpServletResponse response) {
		
		return this.uploadFile(
					request, 
					response, 
					"EXCEL", 
					"/ListaPreciosFile/", 
					Configuration.getInstance().getListaPreciosFolder()
				);
	}
	
	
	private String uploadFile(MultipartHttpServletRequest request, HttpServletResponse response, String application, String urlPath, String filePath) {
		
		try
		{
			Iterator<String> itr =  request.getFileNames();		 
			MultipartFile multipartFile = request.getFile(itr.next());
			
			if(!this.getMIME(application).contains(multipartFile.getContentType()))
				throw new Exception("El tipo de archivo seleccionado no esta permitido");
			
			ArchivoService service = new ArchivoService();
			
			String extension = multipartFile.getOriginalFilename().split("\\.(?=[^\\.]+$)")[1];
			String fileName = service.findFileName(extension);
			
			Archivo archivo = new Archivo();
			archivo.setLongitud(multipartFile.getBytes().length);
			archivo.setTipo(multipartFile.getContentType());
			archivo.setNombreOriginal(multipartFile.getOriginalFilename());
			archivo.setNombre(fileName);
			service.create(archivo);

			multipartFile.transferTo(new File(filePath + fileName));
				
			JSONObject json = new JSONObject();
			json.put("file", archivo);
			json.put("error", "");
			return json.toString();
		}
		catch(GalsException sex) {
			JSONObject json = new JSONObject();
			json.put("error", sex.getErrors().get(0).getDescripcion());
			return json.toString();
		}
		catch(Exception ex) {
			JSONObject json = new JSONObject();
			json.put("error", ex.getMessage());
			return json.toString();
		}
	}
	
	
	@RequestMapping(value = "/Image", method = RequestMethod.POST)
	public @ResponseBody String uploadImage(MultipartHttpServletRequest request, HttpServletResponse response) {
	 
		try
		{
			Iterator<String> itr =  request.getFileNames();
			 
			MultipartFile multipartFile = request.getFile(itr.next());
			
			if(!this.getMIME("IMAGE").contains(multipartFile.getContentType()))
				throw new Exception("El tipo de archivo seleccionado no es una imagen");
			
			ArchivoService service = new ArchivoService();
			
			String extension = multipartFile.getContentType().replace("image/", "");
			String fileName = service.findFileName(extension);
			String tempPath = Configuration.getInstance().getTempFolder();
			
			Archivo archivo = new Archivo();
			archivo.setLongitud(multipartFile.getBytes().length);
			archivo.setTipo(multipartFile.getContentType());
			archivo.setNombreOriginal(multipartFile.getOriginalFilename());
			archivo.setNombre(fileName);
			service.create(archivo);

			multipartFile.transferTo(new File(tempPath + fileName));
				
			JSONObject json = new JSONObject();
			json.put("fileId", archivo.getId());
			json.put("fileName", archivo.getNombre());
			json.put("url", request.getServletContext().getContextPath() + "/TempFile/" + archivo.getNombre());
			json.put("error", "");
			return json.toString();
		}
		catch(GalsException sex) {
			JSONObject json = new JSONObject();
			json.put("error", sex.getErrors().get(0).getDescripcion());
			return json.toString();
		}
		catch(Exception ex) {
			JSONObject json = new JSONObject();
			json.put("error", ex.getMessage());
			return json.toString();
		}
	}
	
	
	@RequestMapping(value = "/Crop", method = RequestMethod.POST)
    public @ResponseBody String cropImage(HttpServletRequest request, HttpServletResponse response) {
		
		try
		{
			int x			 = Integer.parseInt(request.getParameter("x"));
			int y			 = Integer.parseInt(request.getParameter("y"));
			int width		 = Integer.parseInt(request.getParameter("w"));
			int height		 = Integer.parseInt(request.getParameter("h"));
			int imageId		 = Integer.parseInt(request.getParameter("imageId"));
			int imageWidth	 = Integer.parseInt(request.getParameter("imageWidth"));
			int imagenHeight = Integer.parseInt(request.getParameter("imagenHeight"));
			String imageName = request.getParameter("imageName");
	
			String tempPath  = Configuration.getInstance().getTempFolder();
			String smallPath = Configuration.getInstance().getSmallImageFolder();
			String bigPath   = Configuration.getInstance().getBigImageFolder();
			
			BufferedImage bufferImage = ImageIO.read(new File(tempPath + imageName));
			int bufferImageWidth = bufferImage.getWidth();
			int bufferImageHeight = bufferImage.getHeight();
			
			// CROPPING
			BufferedImage out = bufferImage.getSubimage(
					(bufferImageWidth * x) / imageWidth, 
					(bufferImageHeight * y) / imagenHeight, 
					(bufferImageWidth * width) / imageWidth, 
					(bufferImageHeight * height) / imagenHeight
				);
			
			// IMAGENES
			ImageIO.write(this.resizeImage(out, 300, 300), "jpg", new File(bigPath + imageName));
			ImageIO.write(this.resizeImage(out, 80, 80), "jpg", new File(smallPath + imageName));
			
			JSONObject json = new JSONObject();
			json.put("id", imageId);
			json.put("url", request.getServletContext().getContextPath() + "/BigImage/" + imageName);
			json.put("error", "");
			return json.toString();
		}
		catch(Exception ex) {
			JSONObject json = new JSONObject();
			json.put("error", ex.getMessage());
			return json.toString();
		}
    }
	
	
	private BufferedImage resizeImage(BufferedImage originalImage, int width, int height) {
		
        BufferedImage resizedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        Graphics2D graphic = resizedImage.createGraphics();
        graphic.drawImage(originalImage, 0, 0, width, height, null);
        graphic.dispose();

        return resizedImage;
    }
	

	/**************************************
	 * 
	 * 			MIMES PERMITIDOS
	 * 
	 **************************************/
	
	private List<String> getMIME(String application) throws GalsException {
		
		if(application.equals("IMAGE")) {
			return 
				Arrays.asList(
					"image/jpeg", "image/pjpeg",
					"image/jpeg", "image/pjpeg",
					"image/png"
				);
		}		
		else if(application.equals("EXCEL")) {
			return 
				Arrays.asList(
					"application/vnd.ms-excel",
					"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
				);
		}
		
		throw new GalsException("Aplicaci&oacute;n no permitida");
	}
}
